/*
 *   Copyright 2012-present OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

// Packages
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Classes, Dialog, NonIdealState } from '@blueprintjs/core';
import { Descriptions } from 'antd';

// Services
import { RepositoryService } from '../../../services';

// UI
import { ErrorMessage, Loading } from '../../UI';

// Components
const { Item } = Descriptions;

// Constants
const ITEM_SPAN = 3;
const ERROR_MSG = 'Error fetching data from repository';
const UNSAVED = 'Unsaved';

class ViewFileInfoDialog extends Component {
  _isMounted = false;

  state = {
    files: {},
    loading: true,
    error: false,
    errorMsg: ERROR_MSG
  };

  componentDidMount() {
    if (!this.props.fileName.includes(UNSAVED)) {
      this._isMounted = true;
      this.callApiGetRepositories();
    } else {
      this.setState({ loading: false });
    }
  }

  componentWillUnmount() {
    this._isMounted = false;

    if (!this.props.fileName.includes(UNSAVED)) {
      RepositoryService.cancelRequest();
    }
  }

  callApiGetRepositories = () => {
    const { type } = this.props;

    this.setState({
      loading: true,
      error: false
    });

    RepositoryService.getRepositories(type)
      .then(res => {
        if (this._isMounted && res.status === 200) {
          const { data } = res;

          this.setState({ files: this.getFiles(data), loading: false });
        } else {
          if (this._isMounted) {
            this.setState({
              loading: false,
              error: true
            });
          }
        }
      })
      .catch(error => {
        if (this._isMounted) {
          this.setState({
            loading: false,
            error: true
          });
        }
      });
  };

  getFiles(repositoryFiles, files = {}) {
    Object.keys(repositoryFiles).forEach(key => {
      files[repositoryFiles[key].path] = repositoryFiles[key];

      if (repositoryFiles[key].type === 'FOLDER') {
        this.getFiles(repositoryFiles[key].repoObjects, files);
      }
    });

    return files;
  }

  renderDescriptions() {
    const { file, fileName } = this.props;
    const { files } = this.state;
    const fileData = files[file];

    return !fileName.includes(UNSAVED) && fileData ? (
      <Descriptions title={fileName} bordered size="small">
        <Item label="type" span={ITEM_SPAN}>
          {fileData.type}
        </Item>
        <Item label="id" span={ITEM_SPAN}>
          {fileData.id}
        </Item>
        <Item label="path" span={ITEM_SPAN}>
          {fileData.path}
        </Item>
        <Item label="acl" span={ITEM_SPAN}>
          {fileData.acl.join(', ')}
        </Item>
        <Item label="fileType" span={ITEM_SPAN}>
          {fileData.fileType}
        </Item>
      </Descriptions>
    ) : (
      <NonIdealState
        icon="document"
        title={fileName}
        description="Save the workspace to see the file information."
      />
    );
  }

  render() {
    const { onClose } = this.props;
    const { loading, error, errorMsg } = this.state;

    return (
      <Dialog
        title="File Information"
        icon="document"
        canOutsideClickClose={false}
        isOpen={true}
        onClose={onClose}
      >
        <div className={Classes.DIALOG_BODY}>
          {loading ? (
            <Loading className="m-t-20" size={30} center />
          ) : error ? (
            <ErrorMessage
              text={errorMsg}
              callApi={this.callApiGetRepositories}
            />
          ) : (
            this.renderDescriptions()
          )}
        </div>

        {!loading && !error && (
          <div className={Classes.DIALOG_FOOTER}>
            <div className={Classes.DIALOG_FOOTER_ACTIONS}>
              <Button text="Close" onClick={onClose} />
            </div>
          </div>
        )}
      </Dialog>
    );
  }
}

ViewFileInfoDialog.propTypes = {
  file: PropTypes.string,
  fileName: PropTypes.string.isRequired,
  type: PropTypes.string,
  onClose: PropTypes.func.isRequired
};

ViewFileInfoDialog.defaultProps = {
  type: 'saiku'
};

export default ViewFileInfoDialog;
